import React, {Component} from 'react';

import './index.less';

import {base} from 'nc-lightapp-front';

const {
    NCCheckbox
} = base;

/**
 * 
 * leftData : {
 *      key: 11,
 *      display: <div>ddd</div>,
 *      data: {
 *          name: ''
 *      }
 * }
 * 
 * rightData: => 格式与leftData相同 leftData
 * onChange    function (leftData, rightData)
 * 
 * leftTitle : 
 * rightTitle : 
 */

const allCheckTable = {
    all: {
        checked: true
    },
    none: {
        checked: false
    },
    part: {
        checked: false,
        indeterminate: true
    }
};

class Transfer extends Component {
    constructor(props) {
        super(props);

        this.state = {
            leftAllChecked: '', // 左侧全选按钮状态，all, none，part
            rightAllChecked: '', // 右侧全选按钮状态，all, none，part
            leftChecked: {},
            rightChecked: {}, 
            leftCheckedCount: 0,
            rightCheckedCount: 0,
            leftData: props.leftData,
            rightData: props.rightData,
            leftArrowDisabled: true, // 向左的箭头禁用
            rightArrowDisabled: true, // 向右的箭头禁用
        };

        this.changeCheckBox = this.changeCheckBox.bind(this);
        this.changeAllCheckbox = this.changeAllCheckbox.bind(this);
        this.toChange = this.toChange.bind(this);
    }

    toChange(direction) {
        return () => {
            let {
                leftData, 
                rightData,
                leftChecked,
                rightChecked
            } = this.state;

            if('leftData' in this.props) {
                leftData = this.props.leftData
            }
            if('rightData' in this.props) {
                rightData = this.props.rightData
            }

            if(
                (direction === 'toRight' && Object.keys(leftChecked).length <= 0)
                || (direction === 'toLeft' && Object.keys(rightChecked).length <= 0)
             ) {
                return;
            }
            let source = direction === 'toRight' ? [...leftData] : [...rightData];
            let target = direction === 'toRight' ? [...rightData] : [...leftData];
            let checked = direction === 'toRight' ? leftChecked : rightChecked;

            let nSource = [];

            source.forEach((item, index) => {
                if(checked[item.key] && checked[item.key].status) {
                    if(target.length > index) {
                        target.splice(index, 0, item);
                    }
                    else {
                        target.push(item);
                    }
                }
                else {
                    nSource.push(item);
                }
            });

            if(direction === 'toLeft') {
                let tmp = nSource;
                nSource = target;
                target = tmp;
            }

            if(this.props.onChange) {
                this.props.onChange(nSource, target);
            }

            this.setState({
                leftData: nSource,
                rightData: target,
                leftChecked: {},
                rightChecked: {}, 
                leftCheckedCount: 0,
                rightCheckedCount: 0,
                leftAllChecked: 'none',
                rightAllChecked: 'none',
            });
        }
    }

    changeAllCheckbox(type) {
        return (status) => {
            let {
                leftData, 
                rightData
            } = this.state;

            if('leftData' in this.props) {
                leftData = this.props.leftData
            }
            if('rightData' in this.props) {
                rightData = this.props.rightData
            }

            let nChecked = {};

            let data = type === 'left' ? leftData : rightData
            
            data.map((item) => {
                nChecked[item.key] = {
                    status: status,
                    data: item
                };
            });

            let checkedName = `${type}Checked`;
            let checkedAllName = `${type}AllChecked`;

            let typeCount = `${type}CheckedCount`;

            this.setState({
                [checkedName]: nChecked,
                [checkedAllName]: status ? 'all' : 'none',
                [typeCount]: status ? data.length : 0
            });
        }
    }

    changeCheckBox(item, type) {
        return (status) => {
            let {
                leftChecked, 
                leftCheckedCount,
                rightChecked,
                rightCheckedCount,
                leftData,
                rightData
            } = this.state;

            if('leftData' in this.props) {
                leftData = this.props.leftData
            }
            if('rightData' in this.props) {
                rightData = this.props.rightData
            }
            
            let allChecked = '';
            let nCount = 0;
            
            if(type === 'left'){
                nCount = status ? leftCheckedCount + 1 : leftCheckedCount - 1;
            }
            else {
                nCount = status ? rightCheckedCount + 1 : rightCheckedCount - 1;
            }

            if(nCount === 0) {
                allChecked = 'none';
            }
            else if(
                (type === 'left' && nCount === leftData.length) 
                || (type === 'right' && nCount === rightData.length)
            ) {
                allChecked = 'all';
            }
            else {
                allChecked = 'part';
            }

            if(type === 'left') {
                this.setState({
                    leftChecked: {
                        ...leftChecked,
                        [item.key]: {
                            status: status,
                            data: item
                        }
                    },
                    leftCheckedCount: nCount,
                    leftAllChecked: allChecked
                }, () => {
                    if(this.props.onChecked) {
                        this.props.onChecked(type, this.state.leftChecked);
                    }
                });
            }
            else {
                this.setState({
                    rightChecked: {
                        ...rightChecked,
                        [item.key]: {
                            status: status,
                            data: item
                        }
                    },
                    rightCheckedCount: nCount,
                    rightAllChecked: allChecked
                }, () => {
                    this.props.onChecked(type, this.state.rightChecked);
                });
            }
        }
    }

    render() {
        const {
            leftTitle,
            rightTitle,
            leftData:  propsLeftData, 
            rightData: propsRightData,
            className,
            style = {}
        } = this.props;

        let {
            leftAllChecked,
            leftChecked,
            rightAllChecked,
            rightChecked,
            leftData = [],
            rightData = [],
            leftCheckedCount,
            rightCheckedCount
        } = this.state;

        propsLeftData && (leftData = propsLeftData)
        propsRightData && (rightData = propsRightData);

        let rightArrowDisabled = leftCheckedCount <= 0;
        let leftArrowDisabled = rightCheckedCount <= 0;

        return (
            <div 
                className={`transfer-wrapper ${className || ''}`}
                style={style}
            >
                <div className="transfer-left-wrapper">
                    <div className="transfer-title-wrapper">
                        <NCCheckbox
                            {...allCheckTable[leftAllChecked]}
                            onChange={this.changeAllCheckbox('left')}
                        >
                            {leftTitle ? leftTitle : leftData.length}
                        </NCCheckbox>
                    </div>
                    {leftData.map((item, index) => {
                        return (
                            <div className="transfer-item-wrapper">
                                {item.prefix || null}
                                <NCCheckbox
                                    checked={leftChecked[item.key] && leftChecked[item.key].status}
                                    onChange={this.changeCheckBox(item, 'left')}
                                >
                                    {item.display}
                                </NCCheckbox>
                                {item.suffix || null}
                            </div>
                        );
                    })}
                </div>
                <div className="transfer-operation-wrapper">
                    <div className="transfer-operation-button-list">
                        <div 
                            className={`transfer-operation-button-wrapper ${rightArrowDisabled && 'disabled'}`}
                            onClick={this.toChange('toRight')}
                        >
                            >
                        </div>
                        <div 
                            className={`transfer-operation-button-wrapper ${leftArrowDisabled && 'disabled'}`}
                            onClick={this.toChange('toLeft')}
                        >
                            {'<'}
                        </div>
                    </div>
                </div>
                <div className="transfer-right-wrapper">
                    <div className="transfer-title-wrapper">
                        <NCCheckbox
                            {...allCheckTable[rightAllChecked]}
                            onChange={this.changeAllCheckbox('right')}
                        >
                            {rightTitle ? rightTitle : rightData.length}
                        </NCCheckbox>
                    </div>
                    {rightData.map((item, index) => {
                        return (
                            <div className="transfer-item-wrapper">
                                {item.prefix || null}
                                <NCCheckbox
                                    checked={rightChecked[item.key] && rightChecked[item.key].status}
                                    onChange={this.changeCheckBox(item, 'right')}
                                >
                                    {item.display}
                                </NCCheckbox>
                                {item.suffix || null}
                            </div>
                        );
                    })}
                </div>
            </div>
        );
    }
}

export default Transfer;